package com.dycong.common.function;

import lombok.extern.log4j.Log4j;

import java.util.Optional;
import java.util.function.Consumer;

/**
 * Created by yu on 15-7-20.
 */
@Log4j
public class TryToDo {

    private boolean isSuccess;
    private Throwable throwable;


    public TryToDo(boolean isSuccess) {
        this.isSuccess = isSuccess;
    }

    public TryToDo(boolean isSuccess, Throwable throwable) {
        this.isSuccess = isSuccess;
        this.throwable = throwable;
    }

    public static <T> Optional<T> tryToGet(ThrewSupplier<T> supplier) {
        try {
            return Optional.ofNullable(supplier.get());
        } catch (Throwable throwable) {
            log.debug("", throwable);
            return Optional.empty();
        }
    }

    public static TryToDo toTry(ThrewRunnable r) {
        try {
            r.threwRun();
            return new TryToDo(true);
        } catch (Throwable throwable) {
            return new TryToDo(false, throwable);
        }
    }

    public TryToDo andTry(ThrewRunnable r) {
        if (isSuccess) {
            try {
                r.threwRun();
                return new TryToDo(true);
            } catch (Throwable throwable) {
                return new TryToDo(false, throwable);
            }
        } else {
            return new TryToDo(false);
        }
    }


    public TryToDo orTry(ThrewRunnable r) {
        if (!isSuccess) {
            try {
                r.threwRun();
                return new TryToDo(true);
            } catch (Throwable throwable) {
                return new TryToDo(false, throwable);
            }
        } else {
            return new TryToDo(false);  //TODO check this
        }
    }


    public TryToDo ifFailed(Runnable r) {
        if (!isSuccess) {
            r.run();
        }
        return this;
    }


    public TryToDo ifFailed(Consumer<Throwable> throwableConsumer) {
        if (!isSuccess) {
            throwableConsumer.accept(throwable);
        }
        return this;
    }


    public TryToDo ifSuccess(Runnable r) {
        if (isSuccess) {
            r.run();
        }
        return this;
    }


}
